﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace _12306_cnBuyTicket
{
    public partial class Form1 : Form
    {

        /// <summary>
        /// 如果 查到 未完成的订单，赶紧 正常登陆，去付钱吧。
        /// </summary>
        private const string 未完成的订单地址 = "https://dynamic.12306.cn/otsweb/order/myOrderAction.do?method=queryMyOrderNotComplete";
        private const string 登陆页面地址_12306_cn = "https://dynamic.12306.cn/otsweb/login.jsp";
        private const string 登陆提交地址_12306_cn = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";
        private const string 登陆验证码地址 = "https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=lrand";

        private const string 预订提交验证码地址 = "https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=lrandp";

        private const string 预订提交地址 = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=submutOrderRequest";

        private const string 订单提交地址 = "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=confirmPassengerInfoSingle";

        private static string[] ticketCountArray = new string[10];
        private int seqNum = 0;
        HttpClient httpClinet;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            httpClinet = new HttpClient(new Uri(登陆页面地址_12306_cn));
            httpClinet.Headers.Add("Accept-Language", "zh-CN");
            httpClinet.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; BaiduGame; InfoPath.3)");
            //绕过 证书验证 //基础连接已经关闭: 未能为 SSL/TLS 安全通道建立信任关系
            Util.SetCertificatePolicy();

            for (int i = 0; i < ticketCountArray.Length; i++)
            {
                ticketCountArray[i] = "var size='"+i+"';";
            }
            this.dtpTrain_date.Value = DateTime.Now.AddDays(2);
        }

        #region 加载 登陆验证码地址

        //加载验证码
        private void btnLoadValidateCode_Click(object sender, EventArgs e)
        {
            ///byte[] responseData = httpClinet.DownloadData(登陆页面地址_12306_cn);
            // string srcString = Encoding.UTF8.GetString(responseData);
            LoadLoginValidateImage(登陆验证码地址, this.pictureBox1);
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            LoadLoginValidateImage(登陆验证码地址, this.pictureBox1);
        }

        private void pibSureOrderValidateImage_Click(object sender, EventArgs e)
        {
            LoadLoginValidateImage(预订提交验证码地址, this.pibSureOrderValidateImage);
        }
        
        /// <summary>
        /// 加载 登陆验证码地址
        /// </summary>
        private void LoadLoginValidateImage(string url,PictureBox pb)
        {
            try
            {
                this.SetText("开始加载验证码...");
                string tempImageName = "szz.jpg";
                if (File.Exists(tempImageName))
                {
                    File.Delete(tempImageName);
                }
                httpClinet.DownloadFile(new Uri(url), tempImageName);
                FileInfo fi = new FileInfo(tempImageName);
                if (fi != null)
                {
                    fi.Attributes = FileAttributes.Hidden;
                }
                pb.LoadAsync(tempImageName);
                this.SetText("加载验证码完成.");
            }
            catch (Exception ex)
            {
                this.SetText("加载验证码失败:" + ex.Message);
            }

        }
        #endregion

        //开始登陆了
        //系统维护中【维护时间：23:00-06:00】，请稍候访问，谢谢！
        //loginUser.user_name	feiazifeiazi
        //nameErrorFocus	
        //passwordErrorFocus	
        //randCode	6u6v
        //randErrorFocus	
        //user.password	qsiofg4nui
        private void btnLogin_Click(object sender, EventArgs e)
        {
            IList<KeyValue> list = new List<KeyValue>();
            list.Add(new KeyValue() { Key = "loginUser.user_name", Value = this.txtUserName.Text.Trim() });
            list.Add(new KeyValue() { Key = "nameErrorFocus", Value = string.Empty });
            list.Add(new KeyValue() { Key = "passwordErrorFocus", Value = string.Empty });
            list.Add(new KeyValue() { Key = "randErrorFocus", Value = string.Empty });
            list.Add(new KeyValue() { Key = "user.password", Value = this.txtPwd.Text.Trim() });
            list.Add(new KeyValue() { Key = "randCode", Value = this.txtValidateCode.Text.Trim() });
            PostData pd = new PostData();
            string postDataStr = pd.ToString(list);
            try
            {
                string result = httpClinet.PostData(登陆提交地址_12306_cn, postDataStr, Encoding.UTF8, Encoding.UTF8);
                if (result.Contains("先生 ，欢迎您！"))
                {
                    this.SetText("登陆成功了...");
                }
                else if (result.Contains("系统维护中【维护时间：23:00-06:00】，请稍候访问，谢谢！"))
                {
                    this.SetText("五谷不分就:系统维护中【维护时间：23:00-06:00】，请稍候访问，谢谢！");
                }
                else
                {
                    this.SetText("未知错误...." + result);
                }
            }
            catch (Exception ex)
            {
                this.SetText("出错了..." + ex.Message);
            }

            //string postData=

        }


        //我的未完成订单
        private void btnMyOrderNotComplete_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] responseData = httpClinet.DownloadData(未完成的订单地址);
                string srcString = Encoding.UTF8.GetString(responseData);
                if (srcString.Contains("var size='0';\r\n	if(size=='0'){"))
                {
                    this.SetText("还没有订单...");
                }
                else if (srcString.Contains("系统维护中【维护时间：23:00-06:00】，请稍候访问，谢谢！"))
                {
                    this.SetText("我的未完成订单:系统维护中【维护时间：23:00-06:00】，请稍候访问，谢谢！");
                }
                else if (srcString.Contains("                    <th scope=\"col\">车次信息</th>\r\n                    <th scope=\"col\">座位信息</th>\r\n                    <th scope=\"col\">旅客信息</th>\r\n                    <th scope=\"col\">车票状态</th>\r\n"))
                {
                    foreach (var item in ticketCountArray)
                    {
                        if (srcString.Contains(item))
                        {
                            this.SetText("好像抢到票了...快去 正常登陆看吧...");
                            break;
                        }
                    }
                }
                else
                {
                    this.SetText(srcString);
                }
            }
            catch (Exception ex)
            {
                this.SetText("出错了.." + ex.Message);
            }

        }










        //给值
        /// <summary>
        ///  给值
        /// </summary>
        /// <param name="text"></param>
        private void SetText(string text)
        {
            if (this.rtbResult.InvokeRequired)
            {
                Action<string> set = new Action<string>(SetText);
                this.Invoke(set, text);
            }
            else
            {
                this.rtbResult.AppendText(string.Format("{0}.\t{1}\t{2} {3}", (++seqNum), DateTime.Now, text, Environment.NewLine));
                if (seqNum % 100 == 0)
                {
                    VoteLog.AddResult("12606.mi", this.rtbResult.Text);
                    this.rtbResult.Clear();
                }
                this.rtbResult.ScrollToCaret();
            }
        }

        private void btnSubOrder_Click(object sender, EventArgs e)
        {
            string token=YuDing();
            if (string.IsNullOrEmpty(token))
            {
                this.SetText("没有得到org.apache.struts.taglib.html.TOKEN,无法提交");
                return;
            }

            string s= "org.apache.struts.taglib.html.TOKEN=&textfield=%E4%B8%AD%E6%96%87%E6%88%96%E6%8B%BC%E9%9F%B3%E9%A6%96%E5%AD%97%E6%AF%8D&checkbox0=0&orderRequest.train_date=2011-12-31&orderRequest.train_no=6300000K8206&orderRequest.station_train_code=K82&orderRequest.from_station_telecode=GZQ&orderRequest.to_station_telecode=SXF&orderRequest.seat_type_code=&orderRequest.ticket_type_order_num=&orderRequest.bed_level_order_num=000000000000000000000000000000&orderRequest.start_time=14%3A30&orderRequest.end_time=12%3A49&orderRequest.from_station_name=%E5%B9%BF%E5%B7%9E&orderRequest.to_station_name=%E4%B8%89%E9%97%A8%E5%B3%A1%E8%A5%BF&orderRequest.cancel_flag=1&orderRequest.id_mode=Y&passengerTickets=1%2C1%2C%E7%8E%8B%E9%A3%9E%2C1%2C411282198907025011%2C13798422740%2CY&oldPassengers=%E7%8E%8B%E9%A3%9E%2C1%2C411282198907025011&passenger_1_seat=1&passenger_1_ticket=1&passenger_1_name=%E7%8E%8B%E9%A3%9E&passenger_1_cardtype=1&passenger_1_cardno=411282198907025011&passenger_1_mobileno=13798422740&checkbox9=Y&oldPassengers=&checkbox9=Y&oldPassengers=&checkbox9=Y&oldPassengers=&checkbox9=Y&oldPassengers=&checkbox9=Y&randCode=e4dr&orderRequest.reserve_flag=A";
            IList<KeyValue> list = new List<KeyValue>();
            list.Add(new KeyValue() { Key = "org.apache.struts.taglib.html.TOKEN", Value = token });
            list.Add(new KeyValue() { Key = "textfield", Value = "中文或拼音首字母" });
            list.Add(new KeyValue() { Key = "checkbox0", Value = "0" });
            list.Add(new KeyValue() { Key = "orderRequest.train_date", Value = this.dtpTrain_date.Value.ToString("yyyy-MM-dd") });
            list.Add(new KeyValue() { Key = "orderRequest.train_no", Value = "6300000K8206" });
            list.Add(new KeyValue() { Key = "orderRequest.station_train_code", Value = "K82" });
            list.Add(new KeyValue() { Key = "orderRequest.from_station_telecode", Value = "GZQ" });
            list.Add(new KeyValue() { Key = "orderRequest.to_station_telecode", Value = "SXF" });
            list.Add(new KeyValue() { Key = "orderRequest.seat_type_code", Value = "" });
            list.Add(new KeyValue() { Key = "orderRequest.ticket_type_order_num", Value = "" });
            list.Add(new KeyValue() { Key = "orderRequest.bed_level_order_num", Value = "000000000000000000000000000000" });
            list.Add(new KeyValue() { Key = "orderRequest.start_time", Value = "14:30" });
            list.Add(new KeyValue() { Key = "orderRequest.end_time", Value = "12:49" });
            list.Add(new KeyValue() { Key = "orderRequest.from_station_name", Value = "广州" });
            list.Add(new KeyValue() { Key = "orderRequest.to_station_name", Value = "三门峡西" });
            list.Add(new KeyValue() { Key = "orderRequest.cancel_flag", Value = "1" });
            list.Add(new KeyValue() { Key = "orderRequest.id_mode", Value = "Y" });
            list.Add(new KeyValue() { Key = "passengerTickets", Value = "1,1,王飞,1,411282198907025011,13798422740,Y" });
            list.Add(new KeyValue() { Key = "oldPassengers", Value = "王飞,1,411282198907025011" });
            list.Add(new KeyValue() { Key = "passenger_1_seat", Value = "1" });
            list.Add(new KeyValue() { Key = "passenger_1_ticket", Value = "1" });
            list.Add(new KeyValue() { Key = "passenger_1_name", Value = "王飞" });
            list.Add(new KeyValue() { Key = "passenger_1_cardtype", Value = "1" });
            list.Add(new KeyValue() { Key = "passenger_1_cardno", Value = "411282198907025011" });
            list.Add(new KeyValue() { Key = "passenger_1_mobileno", Value = "13798422740" });
            list.Add(new KeyValue() { Key = "checkbox9", Value = "Y" });
            list.Add(new KeyValue() { Key = "oldPassengers", Value = "" });
            list.Add(new KeyValue() { Key = "checkbox9", Value = "Y" });
            list.Add(new KeyValue() { Key = "oldPassengers", Value = "" });
            list.Add(new KeyValue() { Key = "checkbox9", Value = "Y" });
            list.Add(new KeyValue() { Key = "oldPassengers", Value = "" });
            list.Add(new KeyValue() { Key = "checkbox9", Value = "Y" });
            list.Add(new KeyValue() { Key = "oldPassengers", Value = "" });
            list.Add(new KeyValue() { Key = "checkbox9", Value = "Y" });
            list.Add(new KeyValue() { Key = "randCode", Value = this.txtValidateCode.Text.Trim() });
            list.Add(new KeyValue() { Key = "orderRequest.reserve_flag", Value = "A" });
            string postDataStr = new PostData().ToString(list);
            try
            {
                this.SetText("将要提交的参数:" + postDataStr);
                string srcString = httpClinet.PostData(订单提交地址, postDataStr, Encoding.UTF8, Encoding.UTF8);
                if (srcString.Contains("确认客票的状态后再尝试后续操作。谢谢"))
                {
                    this.SetText("确认客票的状态后再尝试后续操作。谢谢");
                }
                else
                {
                    this.SetText(srcString);
                }
            }
            catch (Exception ex)
            {
                this.SetText("出错了..." + ex.Message);
            }
           
        }

        //预订
        private void btnYuDing_Click(object sender, EventArgs e)
        {
            //YuDing();
        }

        /// <summary>
        /// 预订， 获取 org.apache.struts.taglib.html.TOKEN
        /// </summary>
        private string YuDing()
        {
            string postDataStr = "station_train_code=K82&train_date=2012-01-03&seattype_num=&from_station_telecode=GZQ&to_station_telecode=SXF&include_student=00&from_station_telecode_name=%E5%B9%BF%E5%B7%9E&to_station_telecode_name=%E4%B8%89%E9%97%A8%E5%B3%A1&round_train_date=2011-12-30&round_start_time_str=00%3A00--24%3A00&single_round_type=1&train_pass_type=QB&train_class_arr=QB%23D%23Z%23T%23K%23QT%23&start_time_str=00%3A00--24%3A00&lishi=22%3A19&train_start_time=14%3A30&trainno=6300000K8206&arrive_time=12%3A49&from_station_name=%E5%B9%BF%E5%B7%9E&to_station_name=%E4%B8%89%E9%97%A8%E5%B3%A1%E8%A5%BF&ypInfoDetail=1021500000303770000040688000001021503345";
            IList<KeyValue> list = new List<KeyValue>();
            list.Add(new KeyValue() { Key = "station_train_code", Value = "K82" });
            list.Add(new KeyValue() { Key = "train_date", Value = this.dtpTrain_date.Value.ToString("yyyy-MM-dd") });
            list.Add(new KeyValue() { Key = "seattype_num", Value = "" });
            list.Add(new KeyValue() { Key = "from_station_telecode", Value = "GZQ" });
            list.Add(new KeyValue() { Key = "to_station_telecode", Value = "SXF" });
            list.Add(new KeyValue() { Key = "include_student", Value = "00" });
            list.Add(new KeyValue() { Key = "from_station_telecode_name", Value = "广州" });
            list.Add(new KeyValue() { Key = "to_station_telecode_name", Value = "三门峡" });
            list.Add(new KeyValue() { Key = "round_train_date", Value = "2011-12-30" });
            list.Add(new KeyValue() { Key = "round_start_time_str", Value = "00:00--24:00" });
            list.Add(new KeyValue() { Key = "single_round_type", Value = "1" });
            list.Add(new KeyValue() { Key = "train_pass_type", Value = "QB" });
            list.Add(new KeyValue() { Key = "train_class_arr", Value = "QB#D#Z#T#K#QT#" });
            list.Add(new KeyValue() { Key = "start_time_str", Value = "00:00--24:00" });
            list.Add(new KeyValue() { Key = "lishi", Value = "22:19" });
            list.Add(new KeyValue() { Key = "train_start_time", Value = "14:30" });
            list.Add(new KeyValue() { Key = "trainno", Value = "6300000K8206" });
            list.Add(new KeyValue() { Key = "arrive_time", Value = "12%3A49" });
            list.Add(new KeyValue() { Key = "from_station_name", Value = "广州" });
            list.Add(new KeyValue() { Key = "to_station_name", Value = "三门峡西" });
            list.Add(new KeyValue() { Key = "ypInfoDetail", Value = "1021500000303770000040688000001021503345" });//
            postDataStr = new PostData().ToString(list);
            try
            {
                this.SetText("将要提交的参数:"+postDataStr);
                string srcString = httpClinet.PostData(预订提交地址, postDataStr, Encoding.UTF8, Encoding.UTF8);

                MatchData md = new MatchData("<div><input type=\"hidden\" name=\"org.apache.struts.taglib.html.TOKEN\" value=\"", "\">", srcString);
                md.Match(); md.Substring();
                if (!string.IsNullOrEmpty(md.Result))
                {
                    this.SetText("org.apache.struts.taglib.html.TOKEN:" + md.Result);
                }
                else
                {
                    this.SetText(srcString);
                }
                return md.Result;
            }
            catch (Exception ex)
            {
                this.SetText("出错了..."+ex.Message);
            }
            return string.Empty;
            
        }

        
    }

}
